/**
 * 
 */
package tp.pr5.gui;

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JSplitPane;
import javax.swing.JTextField;

import tp.pr5.Constants;
import tp.pr5.RobotEngineObserver;
import tp.pr5.Rotation;

/**
 * @author VICTOR
 *
 */
public class MainWindow implements RobotEngineObserver{

	private JFrame window;
	private RobotPanel robotPanel;
	private NavigationPanel navigationPanel;
	private InfoPanel infoPanel;
	private JComboBox<Rotation> rotationCombo;
	private JTextField idTextField;
	private GUIController controller;
	private JPanel instructionPanel;
	
	/**
	 * Creates the window and the panels using Swing Components. It stores a reference to the RobotEngine object and provides the panels to the robot engine in order to communicate the simulation events.
	 * @param robot The RobotEngine that receives the instructions performed by the action panel
	 */
	public MainWindow(GUIController gameController)
	{
		this.controller = gameController;
		build();
	}
	

	private void build()
	{
		this.window = new JFrame ("Wall-e");
		
		JPanel mainPanel = new JPanel();
		mainPanel.setLayout(new BorderLayout());
	
		JMenuBar menu=new JMenuBar();
		JMenu fileMenu= new JMenu("File");
		menu.add(fileMenu);
		final JMenuItem quitItem=new JMenuItem("Quit");
		fileMenu.add(quitItem);
		this.infoPanel = new InfoPanel();		
		
		quitItem.addActionListener(new ActionListener() { 
			@Override
			public void actionPerformed(ActionEvent e) {
				int option = JOptionPane.showOptionDialog(quitItem, "Are you sure you want to quit?", "sure?", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE, null, null, quitItem);
				if (option == 0)
					controller.executeQuitAction();
			}  
		});
		
		this.window.setJMenuBar(menu);
		this.window.setMinimumSize(new Dimension( 900, 700 ));
		this.navigationPanel = new NavigationPanel(this);
		this.robotPanel = new RobotPanel(this);


		JPanel northPanel = new JPanel();
		northPanel.setLayout(new BorderLayout());
		
		this.instructionPanel = new JPanel();
		this.instructionPanel.setLayout(new GridLayout(4,2,4,4));
		this.instructionPanel.setBorder(BorderFactory.createTitledBorder("Instructions"));
		
		
		this.rotationCombo = new JComboBox<Rotation>();
		this.rotationCombo.addItem(Rotation.LEFT);
		this.rotationCombo.addItem(Rotation.RIGHT);
		
		JButton moveButton = new JButton("MOVE");

		JButton quitButton = new JButton("QUIT");
		JButton turnButton = new JButton("TURN");
		JButton pickButton = new JButton("PICK");
		JButton dropButton = new JButton("DROP");
		JButton operateButton = new JButton("OPERATE");
		this.idTextField = new JTextField();
		
		
		this.instructionPanel.add(moveButton);
		this.instructionPanel.add(quitButton);
		this.instructionPanel.add(turnButton);
		this.instructionPanel.add(this.rotationCombo);

		this.instructionPanel.add(pickButton);
		this.instructionPanel.add(this.idTextField);
		this.instructionPanel.add(dropButton);
		this.instructionPanel.add(operateButton);
		
		JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, this.instructionPanel, this.robotPanel);
		
		northPanel.add(splitPane, BorderLayout.CENTER);
		
		moveButton.addActionListener(moveListener);
		//Quit
		quitButton.addActionListener(quitListener);
		//Turn
		turnButton.addActionListener(turnListener);
		//Pick
		pickButton.addActionListener(pickListener);
		//Drop
		dropButton.addActionListener(dropListener);
		//Operate
		operateButton.addActionListener(operateListener);
		
		mainPanel.add(northPanel, BorderLayout.NORTH);
		mainPanel.add(this.navigationPanel, BorderLayout.CENTER);
		mainPanel.add(this.infoPanel, BorderLayout.SOUTH);
		this.window.setContentPane(mainPanel);
		this.window.pack();
		this.window.setVisible(true);
	
	}
	
	//Move
	ActionListener moveListener = new ActionListener()
	{
        public void actionPerformed(ActionEvent e)
        {
        	controller.executeMoveAction();
        }
    };

	//Quit
    ActionListener quitListener = new ActionListener(){        
    	public void actionPerformed(ActionEvent e)
        {
    		controller.executeQuitAction();
        }
    };
	
	//Turn
    ActionListener turnListener = new ActionListener(){        
    	public void actionPerformed(ActionEvent e)
        {
    		controller.executeTurnAction((Rotation)rotationCombo.getSelectedItem());
        }
    };
	
	//Pick
    ActionListener pickListener = new ActionListener(){        
		public void actionPerformed(ActionEvent e)
        {
			controller.executePickAction(idTextField.getText());
        }
    };
	
	//Drop
    ActionListener dropListener = new ActionListener(){        
		public void actionPerformed(ActionEvent e)
        {
//        	int rowIndex = robotPanel.getTable().getSelectedRow();
//        	if (robotPanel.getTable().getModel().getValueAt(rowIndex, 0) != null)
        	if (robotPanel.getSelectedItem() != null)
        		controller.executeDropAction(robotPanel.getSelectedItem());
        	else
        		raiseError("Must select an item to drop from the object table");
        }
    };
	
	//Operate
    ActionListener operateListener = new ActionListener(){
		public void actionPerformed(ActionEvent e)
        {
//        	int rowIndex = robotPanel.getTable().getSelectedRow();
//        	if (robotPanel.getTable().getModel().getValueAt(rowIndex, 0) != null)
        	if (robotPanel.getSelectedItem() != null)
        		controller.executeOperateAction(robotPanel.getSelectedItem());
        	else
        		raiseError("Must select an item to operate from the object table");
        }
    };

    
    public InfoPanel getInfoPanel()
    {
    	return this.infoPanel;
    }
    
    public NavigationPanel getNavigationPanel()
    {
    	return this.navigationPanel;
    }
    
    public RobotPanel getRobotPanel()
    {
    	return this.robotPanel;
    }
    
    
	@Override
	public void raiseError(String msg) {
		JOptionPane.showOptionDialog(this.window, msg, "OOUCH", JOptionPane.DEFAULT_OPTION, JOptionPane.ERROR_MESSAGE , null, null, this.window);		
	}

	@Override
	public void engineOff(boolean atShip) {
		String msg = "";
		
		this.infoPanel.engineOff(atShip);
		if (atShip)
			msg = Constants.MESSAGE_SAYS + Constants.MESSAGE_FIN_SPACESHIP;
		else
			msg = Constants.MESSAGE_SAYS + Constants.MESSAGE_DIE;
		
		JOptionPane.showOptionDialog(this.window, msg, "BYE BYE", JOptionPane.DEFAULT_OPTION, JOptionPane.WARNING_MESSAGE , null, null, this.window);
		disableButtons();
	}

	@Override
	public void communicationCompleted() {
		this.infoPanel.communicationCompleted();
		JOptionPane.showOptionDialog(this.window, "WALL·E says: I have communication problems. Bye bye", "BYE BYE", JOptionPane.DEFAULT_OPTION, JOptionPane.WARNING_MESSAGE , null, null, this.window);
		this.window.dispose();
		System.exit(0);
	}

	@Override
	public void robotUpdate(int fuel, int recycledMaterial) {
		this.infoPanel.robotUpdate(fuel, recycledMaterial);
		this.robotPanel.robotUpdate(fuel, recycledMaterial);
	}

	@Override
	public void robotSays(String message) {
		this.infoPanel.robotSays(message);
	}

	@Override
	public void communicationHelp(String help) {};
	
	private void disableButtons()
	{
		Component[] com = instructionPanel.getComponents();  
		for (int i = 0; i < com.length; i++) {  
		     com[i].setEnabled(false);  
		}  
	}
}
